package dao

import (
	"context"
	"sale-admin/internal/app/grpc/client"
	"sale-admin/internal/app/grpc/protoc/system_admin"
	"sale-admin/internal/dal"
	"sale-admin/internal/models"
	"strings"

	"192.168.1.75/go-pkg/errorx"
	"gorm.io/gen/field"
	"gorm.io/gorm"
)

type Goods struct{}

// GetGoodsIDByName 通过商品名称获取商品id
func (Goods) GetGoodsIDByName(ctx context.Context, query *dal.Query, goodsNames ...string) []string {
	var goodsIDs []string
	if len(goodsNames) <= 0 {
		return []string{}
	}
	g := query.MaGoodsInfo
	tx := g.WithContext(ctx)
	for _, goodsName := range goodsNames {
		if goodsName != "" {
			tx = tx.Or(g.GoodsName1.Like("%" + goodsName + "%"))
		}
	}
	tx.Pluck(g.GoodsID, &goodsIDs)
	return goodsIDs
}

// Exists 商品是否存在
// merchantID 操作者的商户id
// goodsID 商品id
func (Goods) Exists(ctx context.Context, query *dal.Query, merchantID string, goodsID string) bool {
	g := query.MaGoodsInfo
	count, _ := g.WithContext(ctx).Where(g.GoodsID.Eq(goodsID)).Count()
	return count == 1
}

// Detail 商品详情
func (Goods) Detail(ctx context.Context, query *dal.Query, goodsID string) (*models.MaGoodsInfo, error) {
	g := query.MaGoodsInfo
	return g.WithContext(ctx).Where(g.GoodsID.Eq(goodsID)).Take()
}

// DetailMap
func (Goods) DetailMap(ctx context.Context, query *dal.Query, goodsIDs []string) map[string]*models.MaGoodsInfo {
	g := query.MaGoodsInfo
	detailMap := make(map[string]*models.MaGoodsInfo)
	list, _ := g.WithContext(ctx).Where(g.GoodsID.In(goodsIDs...)).Find()
	for _, record := range list {
		detailMap[record.GoodsID] = record
	}
	return detailMap
}

// HasAuth 是否拥有操作权限
func (Goods) HasAuth(ctx context.Context, query *dal.Query, merchantID, goodsID string) bool {
	g := query.MaGoodsInfo
	tx := g.WithContext(ctx)
	if merchantID != "" && merchantID != "1" {
		cli, err := client.GetSystemAdminClient()
		if err != nil {
			return false
		}
		rsp, err := cli.GetFamilyMerchants(ctx, &system_admin.FamilyMerchantsReq{MerchantId: merchantID})
		if err == nil && rsp != nil {
			tx = tx.Where(g.MerchantID.In(rsp.MerchantIds...))
		}
	}
	count, _ := tx.Where(g.GoodsID.Eq(goodsID)).Count()
	return count == 1
}

// SameNameExist 商品是否存在
func (Goods) SameNameExist(ctx context.Context, db *gorm.DB, merchantID, name string, exceptID string) (count int64, err error) {
	m := dal.Use(db).MaGoodsInfo
	if merchantID == "" {
		return count, errorx.New("商户ID不能为空", -1)
	}
	SystemAdminClient, clientErr := client.GetSystemAdminClient()
	if clientErr != nil {
		return
	}
	req := &system_admin.FamilyMerchantsReq{
		MerchantId: merchantID,
	}
	res, err1 := SystemAdminClient.GetFamilyMerchants(ctx, req)
	if err1 != nil {
		return
	}
	if name == "" {
		return count, errorx.New("商品名称不能为空", -1)
	}
	tx := m.WithContext(ctx).
		Where(m.Deleted.Eq(0)).
		Where(m.MerchantID.In(res.MerchantIds...)).
		Where(m.GoodsName1.Eq(strings.TrimSpace(name)))
	if exceptID != "" {
		tx = tx.Where(m.GoodsID.Neq(exceptID))
	}
	count, _ = tx.Count()
	return
}

type RobotGoodsListType struct {
	GoodsID               string  `json:"goods_id" gorm:"column:goods_id"`
	GoodsName             string  `json:"goods_name" gorm:"column:goods_name"`
	GoodsImage            string  `json:"goods_image" gorm:"column:goods_image"`
	RecommendImage        string  `json:"recommend_image" gorm:"column:recommend_image"`
	AdImage               string  `json:"ad_image" gorm:"column:ad_image"`
	GoodsPrice            float64 `json:"goods_price" gorm:"column:goods_price"`
	GoodsType             int     `json:"goods_type" gorm:"column:goods_type"`
	GoodsClassID          string  `json:"goods_class_id" gorm:"column:goods_class_id"`
	GoodsClassName        string  `json:"goods_class_name" gorm:"column:goods_class_name"`
	GoodsInventory        int     `json:"goods_inventory" gorm:"column:goods_inventory"`
	GoodsReserveInventory int     `json:"goods_reserve_inventory" gorm:"column:goods_reserve_inventory"`
}

// RobotGoodsList 机器商品列表
func (Goods) RobotGoodsList(
	ctx context.Context,
	query *dal.Query,
	robotID string,
	goodsType, goodsClass int,
	goodsID, goodsName string, // 商品类型，商品类别，商品名称
	containerUseStatus int, inventoryStatus int, // 货道状态，库存状态
) (list []*RobotGoodsListType) {
	g := query.MaGoodsInfo       // 商品信息表
	rg := query.MaRobotSalesInfo // 设备库存信息表
	gc := query.MaGoodsClass
	tx := rg.WithContext(ctx).
		Join(g, g.GoodsID.EqCol(rg.GoodsID)).
		LeftJoin(gc, gc.ClassID.EqCol(g.ClassID)).
		Where(rg.RobotName.Eq(robotID)).
		Where(rg.ContainerStatus.Eq(1))
	//1 实物商品 2导流商品 3虚拟类商品 4积分商品5优惠商品6零元购商品'
	if goodsType > 0 {
		tx.Where(g.GoodsType.Eq(goodsType))
	}
	if goodsClass > 0 {
		tx.Where(field.NewInt(g.TableName(), g.GoodsCode.ColumnName().String()).Eq(goodsClass))
	}
	if goodsID != "" {
		tx.Where(g.GoodsID.Eq(goodsID))
	}
	if goodsName != "" {
		tx.Where(g.GoodsName1.Like("%" + goodsName + "%"))
	}
	if containerUseStatus > 0 {
		tx.Where(rg.ContainerUseStatus.Eq(containerUseStatus))
	}
	if inventoryStatus > 0 {
		tx.Where(rg.GoodsInventory.Gt(0))
	}
	tx.Select(
		g.GoodsID,
		g.GoodsName1.As("goods_name"),
		g.GoodsImage,
		g.RecommendImage,
		g.AdImage,
		g.Price.As("goods_price"),
		g.GoodsType,
		g.ClassID.As("goods_class_id"),
		gc.ClassName.As("goods_class_name"),
		rg.GoodsReserveInventory.Sum().As("goods_reserve_inventory"),
		rg.GoodsInventory.Sum().As("goods_inventory"),
	).Group(rg.GoodsID).Scan(&list)
	return
}

func (Goods) ExistsExpressFeeTemplate(
	ctx context.Context,
	db *gorm.DB,
	expressFeeTemplateID string,
) bool {
	var count int64
	db.WithContext(ctx).Model(&models.MaGoodsInfo{}).
		Where("express_fee_template = ?", expressFeeTemplateID).
		Count(&count)
	return count > 0
}
